<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>argp.c</title>
<meta name="generator" content="emacs 26.3; htmlfontify 0.21" />
<style type="text/css"><!-- 
body { font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  color: #dcdccc;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.default   { font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  color: #dcdccc;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.default a { font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  color: #dcdccc;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
span.function-name   { color: #93e0e3;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.function-name a { color: #93e0e3;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
span.comment   { color: #7f9f7f;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.comment a { color: #7f9f7f;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
span.comment-delimiter   { color: #5f7f5f;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.comment-delimiter a { color: #5f7f5f;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
span.variable-name   { color: #dfaf8f;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.variable-name a { color: #dfaf8f;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
span.type   { color: #7cb8bb;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.type a { color: #7cb8bb;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
span.keyword   { color: #f0dfaf;  font-weight: 700;  font-family: Hack;  font-stretch: normal;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.keyword a { color: #f0dfaf;  font-weight: 700;  font-family: Hack;  font-stretch: normal;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
span.string   { color: #cc9393;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.string a { color: #cc9393;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
span.preprocessor   { color: #94bff3;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: none; }
span.preprocessor a { color: #94bff3;  font-family: Hack;  font-stretch: normal;  font-weight: 500;  font-style: normal;  background: #3f3f3f;  font-size: 11pt;  text-decoration: underline; }
 --></style>

    <script type="text/javascript"><!--
  // this function is needed to work around
  // a bug in IE related to element attributes
  function hasClass(obj)
  {
      var result = false;
      if (obj.getAttributeNode("class") != null)
      {
          result = obj.getAttributeNode("class").value;
      }
      return result;
  }

  function stripe(id)
  {
      // the flag we'll use to keep track of
      // whether the current row is odd or even
      var even = false;

      // if arguments are provided to specify the colors
      // of the even & odd rows, then use them;
      // otherwise use the following defaults:
      var evenColor = arguments[1] ? arguments[1] : "#fff";
      var oddColor  = arguments[2] ? arguments[2] : "#ddd";

      // obtain a reference to the desired table
      // if no such table exists, abort
      var table = document.getElementById(id);
      if (! table) { return; }

      // by definition, tables can have more than one tbody
      // element, so we'll have to get the list of child
      // &lt;tbody&gt;s
      var tbodies = table.getElementsByTagName("tbody");

      // and iterate through them...
      for (var h = 0; h < tbodies.length; h++)
      {
          // find all the &lt;tr&gt; elements...
          var trs = tbodies[h].getElementsByTagName("tr");

          // ... and iterate through them
          for (var i = 0; i < trs.length; i++)
          {
              // avoid rows that have a class attribute
              // or backgroundColor style
              if (! hasClass(trs[i]) &&
                  ! trs[i].style.backgroundColor)
              {
                  // get all the cells in this row...
                  var tds = trs[i].getElementsByTagName("td");

                  // and iterate through them...
                  for (var j = 0; j < tds.length; j++)
                  {
                      var mytd = tds[j];

                      // avoid cells that have a class attribute
                      // or backgroundColor style
                      if (! hasClass(mytd) &&
                          ! mytd.style.backgroundColor)
                      {
                          mytd.style.backgroundColor =
                            even ? evenColor : oddColor;
                      }
                  }
              }
              // flip from odd to even, or vice-versa
              even =  ! even;
          }
      }
  }

  function toggle_invis( name )
  {
      var filter =
        { acceptNode:
          function( node )
          { var classname = node.id;
            if( classname )
            { var classbase = classname.substr( 0, name.length );
              if( classbase == name ) { return NodeFilter.FILTER_ACCEPT; } }
            return NodeFilter.FILTER_SKIP; } };
      var walker = document.createTreeWalker( document.body           ,
                                              NodeFilter.SHOW_ELEMENT ,
                                              filter                  ,
                                              false                   );
      while( walker.nextNode() )
      {
          var e = walker.currentNode;
          if( e.style.display == "none" ) { e.style.display = "inline"; }
          else                            { e.style.display = "none";   }
      }
  }
--> </script>
  </head>
  <body onload="stripe('index'); return true;">

<pre><span class="preprocessor">#</span><span class="preprocessor">include</span> <span class="string">&lt;</span><span class="string">stdio.h</span><span class="string">&gt;</span>
<span class="preprocessor">#</span><span class="preprocessor">include</span> <span class="string">&lt;</span><span class="string">argp.h</span><span class="string">&gt;</span>

<span class="keyword">e</span><span class="keyword">nu</span><span class="keyword">m</span> <span class="type">boolean</span> { <span class="variable-name">NO</span>, <span class="variable-name">YES</span> };
<span class="keyword">enum</span> <span class="type">boolea</span><span class="type">n</span> <span class="variable-name">bool</span> = NO;

<span class="keyword">const</span> <span class="type">cha</span><span class="type">r</span> * <span class="variable-name">argp_program_version</span> = <span class="string">&quot;0.1&quot;</span>;
<span class="comment-delimiter">/</span><span class="comment-delimiter">* </span><span class="comment">mail bug reports to </span><span class="comment-delimiter">*/</span>
<span class="keyword">c</span><span class="keyword">onst</span> <span class="type">cha</span><span class="type">r</span> * <span class="variable-name">argp_program_bug_address</span> = <span class="string">&quot;jbranso@fastmail.com&quot;</span>;

<span class="comment-delimiter">/</span><span class="comment-delimiter">/</span><span class="comment">define an argp option called joke  aka &quot;--joke&quot; or &quot;-j&quot;
</span><span class="comment-delimiter">/* </span><span class="comment">struct argp_option argp_options_joke; </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">argp_options_joke.name = &quot;joke&quot;; </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">argp_options_joke.key  = 'j'; </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">/\* This is the value that you see when you print: </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">** ./argp --usage. </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">*\/ </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">argp_options_joke.arg  = &quot;ARG&quot;; //must be provided. </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/</span><span class="comment-delimiter">* </span><span class="comment">argp_options_joke.doc  = &quot;Print a funny joke.&quot;; </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">argp_options_joke.flags = OPTION_ARG_OPTIONAL;  // this option does not need an argument. </span><span class="comment-delimiter">*/</span>

<span class="keyword">s</span><span class="keyword">tatic</span> <span class="keyword">const</span> <span class="keyword">struct</span> <span class="type">argp_optio</span><span class="type">n</span> <span class="variable-name">options</span> [] =
  {
    {<span class="string">&quot;joke&quot;</span>, <span class="string">'j'</span>, <span class="string">&quot;ARG&quot;</span>, OPTION_ARG_OPTIONAL, <span class="string">&quot;Print a funny joke&quot;</span> },
    { 0 }
  };
<span class="comment-delimiter">/</span><span class="comment-delimiter">/ </span><span class="comment">the above can be specified much simplier.  I could actually get rid of the argp_options_joke variable.
</span><span class="comment-delimiter">//</span><span class="comment">struct argp_option options [2] = { &quot;joke&quot;, &quot;j&quot; &quot;STRING&quot;, 0, &quot;Print a funny joke&quot;, { 0 } };
</span>
<span class="comment-delimiter">/</span><span class="comment-delimiter">/</span><span class="comment">define an argp parse function
</span><span class="type">e</span><span class="type">rror_</span><span class="type">t</span> <span class="function-name">argp_parser</span> (<span class="type">int</span> <span class="variable-name">opt</span>, <span class="type">char</span> *<span class="variable-name">arg</span>, <span class="keyword">struct</span> <span class="type">argp_state</span> *<span class="variable-name">state</span>) {
  <span class="keyword">extern</span> <span class="keyword">enum</span> <span class="type">boolea</span><span class="type">n</span> <span class="variable-name">bool</span>;
  <span class="keyword">switch</span> (opt)
    {
      <span class="comment-delimiter">// </span><span class="comment">if this parser function is called on an option that it doesn</span><span class="comment">'</span><span class="comment">t recognize, then don</span><span class="comment">'</span><span class="comment">t do anything.
</span>    <span class="keyword">default</span>:
      <span class="keyword">return</span> ARGP_ERR_UNKNOWN;
    <span class="keyword">case</span> <span class="string">'j'</span>:
      {
        bool = YES;
        <span class="keyword">break</span>;
      }
    }
  <span class="keyword">return</span> 0;
}

<span class="comment-delimiter">/</span><span class="comment-delimiter">* </span><span class="comment">struct argp argp; </span><span class="comment-delimiter">*/</span>
<span class="keyword">s</span><span class="keyword">truct</span> <span class="type">arg</span><span class="type">p</span> <span class="variable-name">argp</span> =
  { options, argp_parser, 0, <span class="string">&quot;Just a simple test argp program&quot;</span> };
<span class="comment-delimiter">/</span><span class="comment-delimiter">* </span><span class="comment">a string containing the basic usage of this program. </span><span class="comment-delimiter">*/</span>

<span class="comment-delimiter">/* </span><span class="comment">If I try to set the argp values manually, I get a segmentation fault. </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">argp.args_doc = &quot;argp [options]&quot;; </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">argp.doc = &quot;Just a simple test argp program!&quot;; </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">argp.options = options; </span><span class="comment-delimiter">*/</span>
<span class="comment-delimiter">/* </span><span class="comment">argp.parser = argp_parser; </span><span class="comment-delimiter">*/</span>

<span class="type">i</span><span class="type">n</span><span class="type">t</span> <span class="function-name">main</span> (<span class="type">int</span> <span class="variable-name">argc</span>, <span class="type">char</span> **<span class="variable-name">argv</span>) {

  <span class="comment-delimiter">/</span><span class="comment-delimiter">/ </span><span class="comment">I still have a bit more to learn with argp, but that</span><span class="comment">'</span><span class="comment">s ok!
</span>  argp_parse (&amp;argp, argc, argv, 0, 0, 0);
  <span class="keyword">if</span> (bool == YES) {
    printf (<span class="string">&quot;What do you call a box full of ducks?\n&quot;</span>);
    printf (<span class="string">&quot;A bunch of quackers.\n&quot;</span>);
  }

  <span class="keyword">return</span> 0;
}
</pre>

 </body>
</html>
